package com.bckj.fastboot.core.extra.retry;

import com.bckj.fastboot.core.jackson.JsonUtils;
import lombok.Setter;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;

@Setter
@Component
@Scope("prototype")
public class FastRetryTemplate {

    private final RetryProducer retryProducer;

    private int maxRetryCount;
    private long initialInterval;
    private int multiplier;
    private String className;
    private String methodName;
    private Object[] args;

    public FastRetryTemplate(RetryProducer retryProducer) {
        this.retryProducer = retryProducer;
    }

    public <T> T execute(Supplier<T> supplier) {
        try {
            return supplier.get();
        } catch (Exception e) {
            RetryContext retryContext = new RetryContext();
            retryContext.setRetryCount(1);
            retryContext.setMaxRetryCount(maxRetryCount);
            retryContext.setInitialInterval(initialInterval);
            retryContext.setMultiplier(multiplier);
            retryContext.setClassName(className);
            retryContext.setMethodName(methodName);
            retryContext.setArgs(toArgsJson());
            retryContext.setArgTypes(toArgTypesJson());
            long delaySeconds = retryContext.getInitialInterval();
            retryProducer.sendRetryMessage(retryContext, delaySeconds);
            throw e;
        }
    }

    private List<String> toArgsJson() {
        return Arrays.stream(args).map(JsonUtils::toJsonStr).toList();
    }

    private List<String> toArgTypesJson() {
        return Arrays.stream(args).map(Object::getClass).map(Class::getName).toList();
    }
}
